﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ext.Net;
using WEB.BLL;
using System.Web.Security;
using WEB.BLL.Services;
using WEB.BLL.Entities;
using System.Web.UI;
using WEB.Core.Util;
using WEB.Exceptions;

namespace WEB.Core.Controls
{
    public class BasePageChart : BasePage
    {
        public enum ChartType
        {
            Line,
            Pie,
            Colum
        }

        protected class ChartSeries
        {

            public ChartSeries()
            {
                Name = "null";
                Values = new List<object>();
            }

            public ChartSeries(string Name)
            {
                this.Name = Name;
                this.Values = new List<object>();
            }

            public ChartSeries(string Name, List<object> Value)
            {
                this.Name = Name;
                this.Values = Value;
            }

            public string Name { get; set; }
            public List<object> Values { get; set; }

            public override string ToString()
            {
                return ToString(ChartType.Line);
            }

            public string ToString(ChartType type)
            {
                List<string> _Temp = new List<string>();
                foreach (var item in this.Values)
                {
                    _Temp.Add(item.ToString().Replace(',','.'));
                }
                switch (type)
                {
                    case ChartType.Pie:
                        return string.Format("name: \'{0}\', y: {1:0}", this.Name, string.Join(",", _Temp.ToArray()));
                    default:
                        return string.Format("name: \'{0}\', data: [{1:0}]", this.Name, string.Join(",", _Temp.ToArray()));
                }
            }
        }

        protected class BaseChart
        {
            public BaseChart()
            {
                xCategories = new List<string>();
                Seriers = new List<ChartSeries>();
                Width = Height = 0;
                this.Type = ChartType.Line;
            }

            public BaseChart(ChartType Type)
            {
                xCategories = new List<string>();
                Seriers = new List<ChartSeries>();
                Width = Height = 0;
                this.Type = Type;
            }

            #region
            public string Title { get; set; }
            public string SubTitle { get; set; }
            public string xTitle { get; set; }
            public List<string> xCategories { get; set; }
            public string yTitle { get; set; }
            public List<ChartSeries> Seriers { get; set; }
            public ChartType Type { get; set; }

            public int Width { get; set; }
            public int Height { get; set; }
            #endregion

            #region
            public ChartSeries LastSerier
            {
                get { return Seriers[Seriers.Count - 1]; }
                set { Seriers[Seriers.Count - 1] = value; }
            }
            #endregion

            #region
            #region Protected
            protected string xCategoriesToString()
            {
                if (xCategories.Count < 1)
                    return "[]";
                string _temp = "";
                foreach (var item in xCategories)
                {
                    _temp += String.Format(",{0}", ToStringJS(item));
                }
                return String.Format("[{0}]", _temp.Remove(0, 1));
            }

            protected string SeriersToString()
            {
                if (Seriers.Count < 1)
                    return "[]";
                string _temp = "";
                foreach (var item in Seriers)
                {
                    _temp += String.Format(",{0}", "{" + item.ToString(this.Type) + "}");
                }
                return String.Format("[{0}]", _temp.Remove(0, 1));
            }

            protected string ToStringJS(string String)
            {
                if (String != null)
                    return String.Format("\'{0}\'", String);
                else
                    return "null";
            }
            protected string ToStringJS(int Int)
            {
                if (Int > 0)
                    return String.Format("{0}", Int);
                else
                    return "null";
            }
            #endregion

            #region Public
            public void AddSerier(string Name)
            {
                Seriers.Add(new ChartSeries(Name));
            }

            public void AddSerier(string Name, params object[] Values)
            {
                Seriers.Add(new ChartSeries(Name, Values.ToList()));
            }

            public string CreateFunction(string FunctionName)
            {
                return String.Format("{0}({1},{2},{3},{4},{5},{6},{7},{8});",
                                       FunctionName,            //{0}
                                       ToStringJS(Title),       //{1}
                                       ToStringJS(SubTitle),    //{2}
                                       ToStringJS(Width),       //{3}
                                       ToStringJS(Height),      //{4}
                                       ToStringJS(xTitle),      //{5}
                                       ToStringJS(yTitle),      //{6}
                                       xCategoriesToString(),   //{7}
                                       SeriersToString());      //{8}
            }
            #endregion
            #endregion
        }

        public BasePageChart(string screenId)
            : base(screenId)
        {
            
        }

        protected override void CheckDashboard()
        {
            base.CheckDashboard();
            var _temp = (Component)FindControl("fpSearch");
            if (_temp != null)
                _temp.Hidden = IsDashboard;
        }

        /// <summary>
        /// Vẽ chart
        /// </summary>
        /// <param name="FunctionName">Tên hàm JavaScrirt vẽ chart</param>
        /// <param name="ResourceManagerName">Tên ResourceManager của trang</param>
        /// <param name="Chart">Thông tin chart cần vẽ</param>
        protected void PaidChart(string FunctionName, string ResourceManagerName, BaseChart Chart)
        {
            var _ResourceManager = (ResourceManager)FindControl(ResourceManagerName);
            if (_ResourceManager != null)
                _ResourceManager.RegisterOnReadyScript(Chart.CreateFunction(FunctionName));
        }

        /// <summary>
        /// Vẽ chart
        /// </summary>
        /// <param name="FunctionName">Tên hàm JavaScrirt vẽ chart</param>
        /// <param name="Chart">Thông tin chart cần vẽ</param>
        protected void PaidChart(string FunctionName, BaseChart Chart)
        {
            PaidChart(FunctionName, "ResourceManager", Chart);
        }

        /// <summary>
        /// Vẽ chart
        /// </summary>
        /// <param name="Chart">Thông tin chart cần vẽ</param>
        protected void PaidChart(BaseChart Chart)
        {
            PaidChart("Paint", Chart);
        }

        protected override void AddPageScript()
        {
            base.AddPageScript();
            AddScript("jquery.min.js");
            AddScript("highcharts.js");
            if (IsExport && !IsDashboard)
                AddScript("exporting.js");
        }

        protected virtual void SetDateSearch()
        {
            var dfDayTo = (DateField)FindControl("dfDayTo");
            var dfDayFrom = (DateField)FindControl("dfDayFrom");
            var cboMonFrom = (ComboBox)FindControl("cboMonFrom");
            var cboMonTo = (ComboBox)FindControl("cboMonTo");
            var cboMonYearFrom = (ComboBox)FindControl("cboMonYearFrom");
            var cboMonYearTo = (ComboBox)FindControl("cboMonYearTo");
            var cboYearFrom = (ComboBox)FindControl("cboYearFrom");
            var cboYearTo = (ComboBox)FindControl("cboYearTo");
            var rdSelectMon = (Radio)FindControl("rdSelectMon");

            if (rdSelectMon != null)
                rdSelectMon.Checked = true;

            DateTime _Temp = DateTime.Now;

            if (dfDayTo != null && dfDayFrom != null)
            {
                dfDayTo.SelectedValue = _Temp;
                dfDayFrom.SelectedValue = _Temp.AddDays(-12);
            }

            if (cboMonFrom != null && cboMonTo != null && cboMonYearFrom != null && cboMonYearTo != null)
            {
                if (cboMonYearTo.SelectedIndex > 0)
                    cboMonYearFrom.SelectedIndex = cboMonYearTo.SelectedIndex - 1;
                else
                {
                    cboMonYearFrom.SelectedIndex = cboMonYearTo.SelectedIndex;
                    cboMonFrom.Value = 1;
                }
            }

            if (cboYearFrom != null && cboYearTo != null)
            {
                if (cboYearTo.SelectedIndex > 11)
                    cboYearFrom.SelectedIndex = cboYearTo.SelectedIndex - 12;
                else
                    cboYearFrom.SelectedIndex = 0;
            }
        }

        protected virtual bool CheckDate(out DateTime FromDate, out DateTime ToDate, out string FormatDate, out string DateName)
        {
            var dfDayTo = (DateField)FindControl("dfDayTo");
            var dfDayFrom = (DateField)FindControl("dfDayFrom");
            var cboMonFrom = (ComboBox)FindControl("cboMonFrom");
            var cboMonTo = (ComboBox)FindControl("cboMonTo");
            var cboMonYearFrom = (ComboBox)FindControl("cboMonYearFrom");
            var cboMonYearTo = (ComboBox)FindControl("cboMonYearTo");
            var cboYearFrom = (ComboBox)FindControl("cboYearFrom");
            var cboYearTo = (ComboBox)FindControl("cboYearTo");
            var rdSelectDay = (Radio)FindControl("rdSelectDay");
            var rdSelectMon = (Radio)FindControl("rdSelectMon");

            int _Max = 40;

            if (rdSelectDay.Checked)
            {
                FormatDate = "dd/MM/yyyy";
                DateName = "Ngày";
                FromDate = Convert.ToDateTime(dfDayFrom.SelectedValue);
                ToDate = Convert.ToDateTime(dfDayTo.SelectedValue);
                if (dfDayFrom.SelectedValue == null)
                {
                    X.Msg.Alert("Notice", "<br>Please select <b>Day starts</b> in <b>Find by day<b>").Show();
                    return false;
                }
                if (dfDayTo.SelectedValue == null)
                {
                    X.Msg.Alert("Notice", "<br>Please select <b>Days ends</b> in <b>Find by day<b>").Show();
                    return false;
                }
                if (FromDate > ToDate)
                {
                    X.Msg.Alert("Notice", "Day starts must larger than day ends.<br>Please reselect <b>Find by day<b>").Show();
                    return false;
                }
                if ((ToDate - FromDate).TotalDays > _Max)
                {
                    X.Msg.Alert("Notice", "The period is too long.<br>Please reselect <b>Find by day<b>").Show();
                    return false;
                }
            }
            else if (rdSelectMon.Checked)
            {
                FormatDate = "MM/yyyy";
                DateName = "Month";
                FromDate = new DateTime(Util.Util.Obj2Int(cboMonYearFrom.Value), Util.Util.Obj2Int(cboMonFrom.SelectedItem.Value), 1);
                ToDate = new DateTime(Util.Util.Obj2Int(cboMonYearTo.Value), Util.Util.Obj2Int(cboMonTo.SelectedItem.Value), 1);
                if (FromDate > ToDate)
                {
                    X.Msg.Alert("Notice", "Month starts must larger than Month end.<br>Please reselect <b>Find by month<b>").Show();
                    return false;
                }
                if (((Util.Util.Obj2Int(cboMonYearTo.Value) - Util.Util.Obj2Int(cboMonYearFrom.Value)) * 12 + (Util.Util.Obj2Int(cboMonYearTo.Value) - Util.Util.Obj2Int(cboMonYearFrom.Value))) > _Max)
                {
                    X.Msg.Alert("Notice", "The period is too long.<br>Please reselect <b>Find by month<b>").Show();
                    return false;
                }
            }
            else
            {
                FormatDate = "yyyy";
                DateName = "Năm";
                FromDate = new DateTime(Util.Util.Obj2Int(cboYearFrom.Value), 1, 1);
                ToDate = new DateTime(Util.Util.Obj2Int(cboYearTo.Value), 1, 1);
                if (FromDate > ToDate)
                {
                    X.Msg.Alert("Notice", "Year starts must larger than year end.<br>Please reselect <b>Find by year<b>").Show();
                    return false;
                }
                if ((Util.Util.Obj2Int(cboYearTo.Value) - Util.Util.Obj2Int(cboYearFrom.Value)) > _Max)
                {
                    X.Msg.Alert("Notice", "The period is too long.<br>Please reselect <b>Find by year<b>").Show();
                    return false;
                }
            }
            return true;
        }
    }
}
